#ifndef __ZBUS_RPC_PROCESSOR_H__
#define __ZBUS_RPC_PROCESSOR_H__  
 
#include "RpcInvoker.h"
#include "ThreadPool.h"

#include <map>
#include <mutex> 

namespace zbus {

	typedef std::function<Json::Value(std::vector<Json::Value>&)> MethodJJ;
	typedef std::function<Json::Value(std::vector<Json::Value>&, Message*)> MethodJJM;  
	typedef std::function<Message*(std::vector<Json::Value>&)> MethodMJ;
	typedef std::function<Message*(std::vector<Json::Value>&, Message*)> MethodMJM;
	typedef std::function<Message*(Message*)> MethodMM;
	typedef std::function<Message*()> MethodM;
	
	struct Method {
		enum MethodType
		{
			JJ,
			JJM,
			VJ,
			MJ,
			MJM,
			MM,
			M
		};

		MethodJJ jj; 
		MethodJJM jjm;   
		MethodMJ mj;   
		MethodMJM mjm; 
		MethodMM mm;    
		MethodM m;    

		MethodType type; 
	};

	class ZBUS_API RpcProcessor { 
	public: 
		ThreadPool threadPool;
		RpcProcessor(int threadPoolSize = 1);
		void addMethod(std::string module, std::string methodName, MethodJJ method);
		void addMethod(std::string module, std::string methodName, MethodJJM method); 
		void addMethod(std::string module, std::string methodName, MethodMJ method);
		void addMethod(std::string module, std::string methodName, MethodMJM method);
		void addMethod(std::string module, std::string methodName, MethodMM method);
		void addMethod(std::string module, std::string methodName, MethodM method);

		void handleAsync(Message* reqMsg, MqClient* client); 
		virtual void handle(Message* reqMsg, MqClient* client); 

	protected:
		virtual Method* findMethod(Request* req);
	private:
		std::map<std::string, Method> methodTable;
		mutable std::mutex methodMutex; 
	};  

}
#endif
